// https://www.w3cschool.cn/nodejs/nodejs-buffer.html
/** 
 * 在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例，
 * 但是Buffer对内存的权限操作相比很大，可以直接捕获一些敏感信息，
 * 所以在v6.0以后，官方文档里面建议使用 Buffer.from()  接口去创建Buffer对象。
*/
const buf = Buffer.from('w3cschool', 'ascii')
console.log(buf.toString()) //使用默认的 'utf8' 编码
console.log(buf.toString('hex')) //使用 'hex' 编码
console.log(buf.toString('base64')) //使用 'base64' 编码
console.log(buf.toString('ascii', 0, 5)) //使用 'ascii' 编码, 并输出: w3csc
console.log(buf.toString('utf8', 0, 5)) //使用 'utf8' 编码, 并输出: w3csc
console.log(buf.toString(undefined, 0, 5)) //使用默认的 'utf8' 编码, 并输出w3csc


// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);

// 创建一个长度为 10、且用 0x1 填充的 Buffer。 
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快，
// 但返回的 Buffer 实例可能包含旧数据，
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);

// 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');

// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf6 = Buffer.from('tést', 'latin1');



/** 
 * 写入缓冲区
 * 语法
 * buf.write(string[, offset[, length]][, encoding])
 * 
 * 参数
 * string - 写入缓冲区的字符串。
 * offset - 缓冲区开始写入的索引值，默认为 0 。
 * length - 写入的字节数，默认为 buffer.length
 * encoding - 使用的编码。默认为 'utf8' 。
 * 根据 encoding 的字符编码写入 string 到 buf 中的 offset 位置。 length 参数是写入的字节数。 如果 buf 没有足够的空间保存整个字符串，则只会写入 string 的一部分。 只部分解码的字符不会被写入。
 * 
 * 返回值
 * 返回实际写入的大小。如果 buffer 空间不足， 则只会写入部分字符串。
*/
const buf7 = Buffer.alloc(256);
const len = buf7.write("www.w3cschool.cn");
console.log("写入字节数 : " + len);

/** 
 * 从缓冲区读取数据
 * 语法
 * buf.toString([encoding[, start[, end]]])
 * 
 * 参数
 * encoding - 使用的编码。默认为 'utf8' 。
 * start - 指定开始读取的索引位置，默认为 0。
 * end - 结束位置，默认为缓冲区的末尾。
 * 
 * 返回值
 * 解码缓冲区数据并使用指定的编码返回字符串。
*/

const buf8 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
console.log(JSON.stringify(buf8)) // 此时字符串化Buffer实例，会隐式调用该对象toJSON()
console.log(buf8.toJSON())

/** 
 * 缓冲区合并
 * 语法
 * Buffer.concat(list[, totalLength])
 * 
 * 参数
 * list - 用于合并的 Buffer 对象数组列表。
 * totalLength - 指定合并后Buffer对象的总长度。
 * 
 * 返回值
 * 返回一个多个成员合并的新 Buffer 对象。
*/
var buffer1 = Buffer.from(('w3cschool编程狮'));
var buffer2 = Buffer.from(('www.w3cschool.cn'));
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 内容: " + buffer3.toString());

/** 
 * 缓冲区比较
 * 语法
 * buf.compare(otherBuffer);
 * 
 * 参数
 * otherBuffer - 与 buf 对象比较的另外一个 Buffer 对象。
 * 
 * 返回值
 * 返回一个数字，表示 buf 在 otherBuffer 之前，之后或相同。
*/

var buffer1 = Buffer.from('ABC');
var buffer2 = Buffer.from('ABCD');
var result = buffer1.compare(buffer2);

if(result < 0) {
   console.log(buffer1 + " 在 " + buffer2 + "之前");
}else if(result == 0){
   console.log(buffer1 + " 与 " + buffer2 + "相同");
}else {
   console.log(buffer1 + " 在 " + buffer2 + "之后");
}


/** 
 * 拷贝缓冲区
 * 语法
 * buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
 * 
 * 参数
 * targetBuffer - 要拷贝的 Buffer 对象。
 * targetStart - 数字, 可选, 默认: 0
 * sourceStart - 数字, 可选, 默认: 0
 * sourceEnd - 数字, 可选, 默认: buffer.length
 * 
 * 返回值
 * 没有返回值。
*/

var buffer1 = Buffer.from('abcdefghijkl');
var buffer2 = Buffer.from('W3CSCHOOL');

//将 buffer2 插入到 buffer1 指定位置上
buffer2.copy(buffer1, 2);

console.log(buffer1.toString());

/** 
 * 缓冲区裁剪
 * 语法
 * buf.slice([start[, end]])
 * 
 * 参数
 * start - 数字, 可选, 默认: 0
 * end - 数字, 可选, 默认: buffer.length
 * 
 * 返回值
 * 返回一个新的缓冲区，它和旧缓冲区指向同一块内存，但是从索引 start 到 end 的位置剪切。
*/
var buffer1 = Buffer.from('w3cschool');
// 剪切缓冲区
var buffer2 = buffer1.slice(0,2);
console.log("buffer2 content: " + buffer2.toString());